import {
  Injectable,
  UnauthorizedException,
  NotFoundException,
  ConflictException,
  ForbiddenException,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './entities/user.entity';
import { UserQueryDto, UserEditDto } from './dto/user.dto';
import {
  UserRole,
  UserStatus,
  UserLanguage,
  UserTheme,
  UserNavigation,
} from './enums/user.enum';
import * as bcrypt from 'bcryptjs';
import { Const } from './enums/const';

@Injectable()
export class AuthService {
  constructor(
    @InjectRepository(User)
    private userRepository: Repository<User>,
    private jwtService: JwtService,
  ) {}

  async validateUser(
    username: string,
    password: string,
  ): Promise<Omit<User, 'password'>> {
    const user = await this.userRepository.findOne({
      where: { username },
      select: [
        'id',
        'username',
        'password',
        'role',
        'status',
        'email',
        'phone',
        'avatar',
        'language',
        'theme',
        'navigation',
      ],
    });

    if (!user) {
      throw new UnauthorizedException('用户名或密码错误');
    }

    const isPasswordValid = await bcrypt.compare(password, user.password);
    if (!isPasswordValid) {
      throw new UnauthorizedException('用户名或密码错误');
    }

    if (user.status === UserStatus.DISABLED) {
      throw new UnauthorizedException('账号已被禁用');
    }

    const { password: _, ...result } = user;
    return result;
  }

  async login(user: Omit<User, 'password'>) {
    const payload = {
      username: user.username,
      sub: user.id,
      role: user.role,
    };
    return {
      access_token: this.jwtService.sign(payload),
      user: {
        id: user.id,
        username: user.username,
        email: user.email,
        phone: user.phone,
        role: user.role,
        status: user.status,
        avatar: user.avatar,
        language: user.language,
        theme: user.theme,
        navigation: user.navigation,
      },
    };
  }

  async register(
    username: string,
    email: string,
    password: string,
    phone?: string,
  ): Promise<User> {
    // 检查用户名是否已存在
    const existingUsername = await this.userRepository.findOne({
      where: { username },
    });
    if (existingUsername) {
      throw new ConflictException('用户名已存在');
    }

    // 检查邮箱是否已存在
    const existingEmail = await this.userRepository.findOne({
      where: { email },
    });
    if (existingEmail) {
      throw new ConflictException('邮箱已被注册');
    }

    // 暂时注释掉手机号唯一性检查
    // if (phone) {
    //   const existingPhone = await this.userRepository.findOne({ where: { phone } });
    //   if (existingPhone) {
    //     throw new ConflictException('手机号已存在');
    //   }
    // }

    // 加密密码
    const hashedPassword = await bcrypt.hash(password, 10);

    // 创建新用户
    const newUser = new User();
    newUser.username = username;
    newUser.email = email;
    newUser.password = hashedPassword;
    newUser.phone = Const.NULL; // 使用空字符串代替 null
    newUser.role = UserRole.USER;
    newUser.status = UserStatus.ENABLED;
    newUser.language = UserLanguage.ZH;
    newUser.theme = UserTheme.MODAL;
    newUser.navigation = UserNavigation.SIDE;

    return this.userRepository.save(newUser);
  }

  async getUserProfile(userId: number): Promise<Omit<User, 'password'>> {
    const user = await this.userRepository.findOne({
      where: { id: userId },
      select: [
        'id',
        'username',
        'email',
        'phone',
        'role',
        'status',
        'avatar',
        'language',
        'theme',
        'navigation',
        'createdAt',
        'updatedAt',
      ],
    });

    if (!user) {
      throw new NotFoundException('用户不存在');
    }
    return user;
  }

  async getUsers(query: UserQueryDto) {
    const { page = 1, limit = 10 } = query;
    const [items, total] = await this.userRepository.findAndCount({
      select: [
        'id',
        'username',
        'email',
        'phone',
        'role',
        'status',
        'avatar',
        'language',
        'theme',
        'navigation',
        'createdAt',
        'updatedAt',
      ],
      skip: (page - 1) * limit,
      take: limit,
      order: { createdAt: 'DESC' },
    });

    return {
      items,
      total,
      page,
      limit,
    };
  }

  async updateUser(
    userId: number,
    updateUserDto: UserEditDto,
    currentUser: User,
  ): Promise<Omit<User, 'password'>> {
    const user = await this.userRepository.findOne({ where: { id: userId } });
    if (!user) {
      throw new NotFoundException('用户不存在');
    }

    // 检查修改权限
    if (currentUser.role === UserRole.USER) {
      // 普通用户只能修改自己的信息
      if (currentUser.id !== userId) {
        throw new ForbiddenException('无权修改其他用户信息');
      }
      // 角色相同的用户只能修改自己的信息
      if (updateUserDto.role && currentUser.role !== updateUserDto.role) {
        throw new ForbiddenException('无权修改用户角色');
      }
    }

    // 管理员可以修改任何用户的信息和权限
    // 只更新提供的字段
    if (updateUserDto.username) user.username = updateUserDto.username;
    if (updateUserDto.email) user.email = updateUserDto.email;
    if (updateUserDto.phone) user.phone = updateUserDto.phone;
    if (updateUserDto.password)
      user.password = await bcrypt.hash(updateUserDto.password, 10);
    if (updateUserDto.role) user.role = updateUserDto.role;
    if (updateUserDto.status) user.status = updateUserDto.status;
    if (updateUserDto.avatar) user.avatar = updateUserDto.avatar;
    if (updateUserDto.language) user.language = updateUserDto.language;
    if (updateUserDto.theme) user.theme = updateUserDto.theme;
    if (updateUserDto.navigation) user.navigation = updateUserDto.navigation;

    await this.userRepository.save(user);

    // 返回更新后的用户信息（不包含密码）
    const { password, ...result } = user;
    return result;
  }

  async deleteUser(userId: number, currentUser: User): Promise<void> {
    const user = await this.userRepository.findOne({ where: { id: userId } });
    if (!user) {
      throw new NotFoundException('用户不存在');
    }

    // 检查删除权限
    if (currentUser.role === UserRole.USER) {
      throw new ForbiddenException('无权删除用户');
    }

    // 管理员可以删除任何用户，包括其他管理员
    await this.userRepository.remove(user);
  }
}
